<?php


namespace App\Controller\Api\V1;

use App\Common\BeseController;
use App\Model\Mysql\UserInviteModel;
use App\Model\Mysql\UserModel;
use App\Model\Redis\UserRedis;
use App\Service\AccessTokenRedis;
use App\Service\NumberService;
use App\Service\RedisKeyService;
use extend\wechat\mini\Auth;
use extend\wechat\mini\Encrypt;
use extend\wechat\mini\QRCode;

class Login extends BeseController
{
    /**
     * 判断是否登录
     * @return bool
     */
    public function miniAuth()
    {
        $input = $this->input;

        $config = config('MINI');

        $webUserInfo = Auth::webUserInfo($input['code'], $config['appid'], $config['appsecret']);

        $webUserInfo = json($webUserInfo);

        if (!empty($webUserInfo['errcode'])) return $this->responseError($webUserInfo['errmsg']);

        $decrypt = json_decode($input['user_data'], JSON_UNESCAPED_UNICODE);

//        $webUserInfo['openid'] = 'oXB4A4wr-34d5cibur6hf0RDYHIA';

        $decrypt['openId'] = $webUserInfo['openid'];

        UserRedis::getInstance()->tempUser(RedisKeyService::tempUserToken($webUserInfo['openid']), $decrypt);

        $sessionKey = $webUserInfo['session_key'];

        $openid = $webUserInfo['openid'];

        $id = UserModel::getValue(['mini_openid' => $webUserInfo['openid']]);

        if (empty($id)) {
            return $this->responseSuccess('用户未注册', compact('sessionKey', 'openid'));
        }

        return $this->responseSuccess('获取用户信息成功', $this->insertUser($decrypt));
    }

    /**
     * 注册
     * @return bool
     */
    public function miniLogin()
    {
        $input = $this->input;

        $config = config('MINI');

        $res = Encrypt::decrypt($config['appid'], $input['encryptedData'], $input['iv'], $input['sessionKey'], $decrypt);
        if ($res !== 0) {
            return $this->responseError('解码错误：' . $res);
        }
        $decrypt = json($decrypt);

        // 获取用户信息
        $tempUser = UserRedis::getInstance()->tempUser(RedisKeyService::tempUserToken($input['openid']));

        if (empty($tempUser)) {

            return $this->responseError('请先授权登录', '-1');
        }

        $res = $this->insertUser($tempUser, $decrypt['phoneNumber']);

        return $this->responseSuccess('注册成功', ['token' => $res['token'], 'user_id' => $res['user_id']]);
    }


    /**
     * 获取用户资料
     * @param $openid
     * @return array
     */
    private function getUser($openid)
    {
        $user = UserModel::getOne(['mini_openid' => $openid]);
        // 生成用户标识
        $token = RedisKeyService::userToken("user_id={$user->id}&&openid={$user->mini_openid}&&time=" . time());

        UserRedis::getInstance()->user($token, $user->toArray());

        UserModel::editData(['token' => $token], ['id' => $user['id']]);

        return ['token' => $token, 'user_id' => $user->id];
    }


    /**
     * 保存用户信息
     * @param $mobile
     * @return array|bool
     */
    private function insertUser($tempUser, $mobile = '')
    {
        $input = $this->input;

        $inputData['nickname'] = $tempUser['nickName'];
        $inputData['headimg'] = $tempUser['avatarUrl'];
        $inputData['sex'] = $tempUser['gender'];
        $inputData['mini_openid'] = $tempUser['openId'];
        $inputData['wx_unionid'] = $tempUser['unionId'] ?? '';
        $inputData['country'] = $tempUser['country'];
        $inputData['province'] = $tempUser['province'];
        $inputData['city'] = $tempUser['city'];
        $inputData['login_time'] = time();
        if ($mobile) {
            $inputData['mobile'] = $mobile;
        }
        $userId = UserModel::getValue(['mini_openid' => $tempUser['openId']], 'id');

        if (empty($userId)) {
            $userId = UserModel::addData($inputData);
            $accessToken = AccessTokenRedis::get();
            $data = [
                'scene' => NumberService::userInvite($mobile)
            ];
            $res = QRCode::getUnlimited($accessToken, $data);
            // 写入地址
            $fileName = "image/user/{$userId}.png";
            // 打开文件准备写入
            $file = fopen($fileName, "w");
            // 写入
            fwrite($file, $res);
            // 关闭
            fclose($file);

            UserModel::editData(['invite_img' => config('app.host') . '/' . $fileName, 'invite_code' => $data['scene']], ['id' => $userId]);

            // 判断是否有邀请码
            if (!empty($input['invite_code'])) {
                $pid = UserModel::getValue(['invite_code' => $input['invite_code']]);

                if (!empty($pid)) {
                    UserInviteModel::addData(['pid_id' => $pid, 'user_id' => $userId]);
                }
            }
        } else {
            UserModel::editData($inputData, ['id' => $userId]);
        }
        return $this->getUser($inputData['mini_openid']);
    }
}